package net.risesoft.risebi.collection.web.admin;

import java.sql.Types;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.risesoft.risebi.commons.util.sqlfilter.JsonFilterResolver;
import net.risesoft.risebi.collection.model.Catalog;
import net.risesoft.risebi.collection.model.DbColumn;
import net.risesoft.risebi.collection.model.ReportInstance;
import net.risesoft.risebi.collection.model.ReportWindowPeriod;
import net.risesoft.risebi.collection.model.SoType;
import net.risesoft.risebi.collection.service.CatalogManager;
import net.risesoft.risebi.collection.service.DbMetaDataManager;
import net.risesoft.risebi.collection.service.DynaBeanManager;
import net.risesoft.risebi.collection.service.ReportInstanceManager;
import net.risesoft.risebi.collection.service.ReportWindowPeriodManager;
import net.risesoft.risebi.collection.service.SoTypeManager;
import net.risesoft.risebi.collection.web.BaseAction;
import net.risesoft.risebi.commons.util.GUID;
import net.risesoft.risebi.commons.util.JSONUtil;

import net.sf.json.JSONObject;
import org.apache.commons.beanutils.LazyDynaBean;
import org.apache.log4j.Logger;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;

/**
 * 
 * @author <a href="mailto: baiyibing@gmail.com">王锤</a>
 * @version $Revision$
 * 
 */
@Namespace("/admin/ReportInstanceAction")
public class ReportInstanceAction extends BaseAction {
	private static final long serialVersionUID = -2309021797139911820L;
	private static final Logger logger = Logger.getLogger(ReportInstanceAction.class);

	private ReportWindowPeriodManager reportWindowPeriodManager;
	private CatalogManager catalogManager;
	private DynaBeanManager dynaBeanManager;
	private ReportInstanceManager reportInstanceManager;
	private SoTypeManager soTypeManager;
	private DbMetaDataManager dbMetaDataManager;

	private ReportInstance reportInstance;
	private ReportWindowPeriod reportWindowPeriod;

	private String catalogGuid;
	private String objectGuid;
	private String jsonObjects;
	private String filter;

	private boolean toBeInit;

	public boolean isToBeInit() {
		return toBeInit;
	}

	public void setToBeInit(boolean toBeInit) {
		this.toBeInit = toBeInit;
	}

	public String listTemplate() throws Exception {
		return "listTemplate";
	}

	@Action(value="prepareEdit",
			results={@Result(name="success", location="/admin/reportinstance/reportInstanceEdit.jsp")}
	)
	public String prepareEdit() throws Exception {
		reportWindowPeriod = (ReportWindowPeriod)reportWindowPeriodManager.getObject(ReportWindowPeriod.class, reportWindowPeriod.getGuid());
		
		ArrayList al = new ArrayList();
		List<SoType> lst = soTypeManager.find("from SoType c where c.service.guid='" + this.getDefaultService().getGuid() + "'");
		for (SoType a : lst) {
			LazyDynaBean ldb = new LazyDynaBean();
			ldb.set("guid", a.getGuid());
			ldb.set("name", a.getName());
			al.add(ldb);
		}
		this.json = JSONUtil.getJsonString(null, null, al);

		return SUCCESS;
	}

	@Action(value="prepareAdd",
			results={@Result(name="success", location="/admin/reportinstance/reportInstanceAdd.jsp")}
	)
	public String prepareAdd() throws Exception {
		Catalog catalog = (Catalog)catalogManager.getObject(Catalog.class, this.catalogGuid);
		String tableName = catalog.getTableName().trim().toLowerCase();
		StringBuilder gridConfig = new StringBuilder();		
		try{		
			List<DbColumn> lst = dbMetaDataManager.listAllColumns(tableName);
			for(DbColumn d : lst){
				String column_name = d.getColumn_name().trim().toLowerCase();
				String column_caption = d.getComment().trim().toLowerCase();

				if(!column_name.endsWith("guid")){
					switch(d.getData_type()){
					//整型
					case Types.TINYINT:
					case Types.SMALLINT:
					case Types.INTEGER:
					case Types.BIGINT:
						gridConfig.append("{id: '" + column_name + "', label: '" + column_caption + "', type: 'int'},");
						break;
					//浮点型
					case Types.FLOAT:
					case Types.REAL:
					case Types.DOUBLE:
					case Types.NUMERIC:
					case Types.DECIMAL:
						gridConfig.append("{id: '" + column_name + "', label: '" + column_caption + "', type: 'float'},");
						break;
					//字符串
					case Types.CHAR:
					case Types.VARCHAR:
//					case Types.NCHAR:
//					case Types.NVARCHAR:
						gridConfig.append("{id: '" + column_name + "', label: '" + column_caption + "', type: 'string'},");
						break;
					case Types.LONGVARCHAR:
//					case Types.LONGNVARCHAR:
						break;
					//BOOLEAN
					case Types.BIT:
					case Types.BOOLEAN:
						gridConfig.append("{id: '" + column_name + "', label: '" + column_caption + "', type: 'string'},");
						break;
					//日期型
					case Types.DATE:
						gridConfig.append("{id: '" + column_name + "', label: '" + column_caption + "', type: 'date', format: 'Y-m-d H:i:s'},");
						break;
					case Types.TIME:	
						gridConfig.append("{id: '" + column_name + "', label: '" + column_caption + "', type: 'date', format: 'Y-m-d H:i:s'},");
						break;
					case Types.TIMESTAMP:
						gridConfig.append("{id: '" + column_name + "', label: '" + column_caption + "', type: 'date', format: 'Y-m-d H:i:s'},");
						break;
					//blob
					case Types.BLOB:
						break;
					//clob
					case Types.CLOB:
						break;
					default:
					}
				}
			}		
			String filterConfig = gridConfig.toString();
			if(filterConfig.endsWith(",")){
				filterConfig = filterConfig.substring(0, filterConfig.length()-1);
			}
			
			this.json = filterConfig; 
		}catch(Exception e){
			this.json = "";
			e.printStackTrace();
		}
		
		return SUCCESS;
	}

	@Action(value="removeAll")
	public String removeAll() throws Exception {
		LazyDynaBean ldb = new LazyDynaBean();
		try {

			if ("all".equalsIgnoreCase(this.jsonObjects)) { // 全部删除。
				// 判断报表是否上报了报表。
				Integer count = reportInstanceManager.getCount("select count(*) from ReportInstance r "
						+ "where r.reportWindowPeriod.guid='" + this.objectGuid + "' and r.status>0");
				if (count > 0) {
					ldb.set("success", false);
					ldb.set("reason", "该窗口期已经上报了数据，不允许删除全部!");
				} else {
					reportInstanceManager.execute("delete from ReportInstance r where r.reportWindowPeriod.guid='" + this.objectGuid + "'");
					ldb.set("success", true);
					ldb.set("reason", "删除成功!");
				}
			} else {
				if (this.jsonObjects.trim().length() > 0) {
					String[] ReportInstanceGuids = this.jsonObjects.split(",");
					ReportInstance temp = null;
					for (String ReportInstanceGuid : ReportInstanceGuids) {
						// 判断是否上报了报表，如有报表，则跳过。
						temp = (ReportInstance) reportInstanceManager.getObject(ReportInstance.class, ReportInstanceGuid);
						if (temp.getStatus()!=null && temp.getStatus()>ReportInstance.STATUS_NO) {
							ldb.set("success", false);
							ldb.set("reason", "该名录已经有了填报数据，不允许删除，请在报表查询中先删除该报表的填报数据后再删除名录。");
							this.json = JSONObject.fromObject(ldb).toString();
							return AJAX;
						}
						reportInstanceManager.removeObject(ReportInstance.class, ReportInstanceGuid);
					}
				}
				ldb.set("success", true);
				ldb.set("reason", "删除成功!");
			}

			this.json = JSONObject.fromObject(ldb).toString();
		} catch (Exception e) {
			ldb.set("success", false);
			ldb.set("reason", "删除失败:" + e.getMessage());
			this.json = JSONObject.fromObject(ldb).toString();
		}
		return AJAX;
	}

	@Action(value="edit")
	public String edit() throws Exception {
		if (logger.isDebugEnabled()) {
			logger.debug("reportinstance edit() - start"); //$NON-NLS-1$
		}

		LazyDynaBean ldb = new LazyDynaBean();
		try {
			ReportWindowPeriod reportWindowPeriod = (ReportWindowPeriod) reportWindowPeriodManager.getObject(ReportWindowPeriod.class, this.objectGuid);
			Catalog catalog = (Catalog)catalogManager.getObject(Catalog.class, this.catalogGuid);
			String tableName = catalog.getTableName().trim().toLowerCase();
			
			if ("all".equalsIgnoreCase(this.jsonObjects)) {
				List<HashMap<String,Object>> dynaBeanList = dynaBeanManager.getObjects(tableName);
				for (HashMap<String,Object> dynaBean : dynaBeanList) {
					String soInstanceGuid = (String)dynaBean.get("item_guid");
					ReportInstance ri;					
					List list = reportInstanceManager.find("from ReportInstance ri where ri.reportWindowPeriod.guid='" + this.objectGuid + "' and ri.soInstanceGuid='" + soInstanceGuid + "' and ri.so.guid='" + catalogGuid + "'");
					if(list.size()==0){
						ri = new ReportInstance();
						ri.setGuid(new GUID().toString());
					}else{
						ri = (ReportInstance)list.get(0);
					}
					ri.setReportWindowPeriod(reportWindowPeriod);
					ri.setSo(catalog);
					ri.setReportPeriod(reportWindowPeriod.getReportPeriod());
					ri.setTemplate(reportWindowPeriod.getTemplate());
					ri.setSoInstanceGuid(soInstanceGuid);					
					ri.setSoInstanceCode((String)dynaBean.get("item_code"));
					ri.setSoInstanceName((String)dynaBean.get("item_name"));					
                    ri.setStatus(0);
                    ri.setLockStatus(0);
                    ri.setTabIndex(1D);
                    //ri.setFirstUploadDate(new Date());
                    //ri.setLastModifiedDate(new Date());
                    
                    ri.setApplication(catalog.getApplication());
                    ri.setSpeciality(catalog.getApplication().getSpeciality());
                    ri.setService(catalog.getApplication().getService());
                    ri.setSoType(catalog.getSoType());
                    ri.setReportPeriodType(reportWindowPeriod.getReportPeriod().getReportPeriodType());
					reportInstanceManager.saveObject(ri);
				}
			}else{
				if (this.jsonObjects.trim().length() > 0) {
					String[] soInstanceGuids = this.jsonObjects.split(",");
					for (String soInstanceGuid : soInstanceGuids) {
						ReportInstance ri = new ReportInstance();
						ri.setGuid(new GUID().toString());
						ri.setReportWindowPeriod(reportWindowPeriod);
						ri.setSo(catalog);
						ri.setReportPeriod(reportWindowPeriod.getReportPeriod());
						ri.setTemplate(reportWindowPeriod.getTemplate());
						ri.setSoInstanceGuid(soInstanceGuid);						
						
						HashMap<String,Object> dynaBean = (HashMap<String, Object>)dynaBeanManager.getObject(tableName, soInstanceGuid);
						ri.setSoInstanceCode((String)dynaBean.get("item_code"));
						ri.setSoInstanceName((String)dynaBean.get("item_name"));						
	                    ri.setStatus(0);	                    
	                    ri.setLockStatus(0);
	                    ri.setTabIndex(1D);
	                    //ri.setFirstUploadDate(new Date());
	                    //ri.setLastModifiedDate(new Date());
	                    
	                    ri.setApplication(catalog.getApplication());
	                    ri.setSpeciality(catalog.getApplication().getSpeciality());
	                    ri.setService(catalog.getApplication().getService());
	                    ri.setSoType(catalog.getSoType());
	                    ri.setReportPeriodType(reportWindowPeriod.getReportPeriod().getReportPeriodType());
						reportInstanceManager.saveObject(ri);
					}
				}
			}

			ldb.set("success", true);
			ldb.set("reason", "保存成功!");
			this.json = JSONObject.fromObject(ldb).toString();
		} catch (Exception e) {
			logger.error("reportinstance edit()", e); //$NON-NLS-1$

			ldb.set("success", false);
			ldb.set("reason", "保存失败:" + e.getMessage());
			this.json = JSONObject.fromObject(ldb).toString();
			e.printStackTrace();
		}

		if (logger.isDebugEnabled()) {
			logger.debug("reportinstance edit() - end"); //$NON-NLS-1$
		}
		return AJAX;
	}

	public String Init() throws Exception {
		return "init";
	}

	@Action(value="refreshJson")
	public String refreshJson() throws Exception {
		long startTime = System.currentTimeMillis();

		try {
			if ("jsonSOinstances".equalsIgnoreCase(this.whichJson)) {
				Catalog catalog = (Catalog)catalogManager.getObject(Catalog.class, this.catalogGuid);
				String tableName = catalog.getTableName().trim().toLowerCase();
				
				// 排除已经选择了的。
				String excludeStr = " item_guid not in ( select ri.soInstanceGuid from ReportInstance ri where ri.reportWindowPeriod.guid='" + reportWindowPeriod.getGuid() + "') ";
				
				Map map = null;
				if(filter==null || filter.trim().length()==0){
					map = (Map)dynaBeanManager.getPagedCatalogItems(tableName, excludeStr ,start, limit);		
				}else{
					JsonFilterResolver filterResolver = new JsonFilterResolver();
					String where = filterResolver.getSql(JSONObject.fromObject(this.filter));
					logger.info(this.filter);
					map = (Map)dynaBeanManager.getPagedCatalogItems(tableName, where + " and " + excludeStr, start, limit);
				}
				this.json = JSONUtil.getJsonString(null,null,map);
			} else if ("jsonReportinstances".equalsIgnoreCase(this.whichJson)) {
				if (reportInstance == null) {
					reportInstance = new ReportInstance();
				}
				Map map = reportInstanceManager.getPagedReportInstancesByObject(reportInstance, this.start,this.limit);
				this.json = JSONUtil.getJsonString("include","count,list,guid,soInstanceGuid,soInstanceCode,soInstanceName,soTypeName",map);
			} else if ("jsonSo4defaultApp".equalsIgnoreCase(this.whichJson)) {
				ArrayList al = new ArrayList();	
				List<Catalog> cs = catalogManager.getCatalogWithSoByApp(this.getDefaultApp().getGuid(),false);
				for(Catalog c : cs){
					LazyDynaBean ldb = new LazyDynaBean();
					ldb.set("text", "【" + c.getSoType().getName() +"】：" + c.getName());
					ldb.set("type", "so");
					ldb.set("soGuid", c.getGuid());
					ldb.set("cls", "x-btn-text-icon");
					if(this.getContextPath().endsWith("/")){
						ldb.set("icon", this.getContextPath()+"images/system/fam/user.png");
					}else{
						ldb.set("icon", this.getContextPath()+"/images/system/fam/user.png");
					}					
					al.add(ldb);
				}
				
				if(al.size()==0){
					LazyDynaBean ldb = new LazyDynaBean();
					ldb.set("text", "本应用没有统计调查对象, 请在《服务管理/统计调查任务管理/调查对象》中定义统计调查对象！");
					ldb.set("type", "not so");
					ldb.set("soGuid", "not so");
					ldb.set("cls", "x-btn-text-icon");
					if(this.getContextPath().endsWith("/")){
						ldb.set("icon", this.getContextPath()+"images/system/fam/asterisk_orange.png");
					}else{
						ldb.set("icon", this.getContextPath()+"/images/system/fam/asterisk_orange.png");
					}					
					al.add(ldb);
				}
				this.json = JSONUtil.getJsonString(null, null, al);	
			} else {
				this.json = "[]";
			}
		} catch (Exception e) {
			this.json = "[]";
			e.printStackTrace();
		}
		
		long endTime = System.currentTimeMillis();
		System.out.println("refreshJson Time Used："+(endTime-startTime));
		
		return AJAX;
	}

	public ReportWindowPeriodManager getReportWindowPeriodManager() {
		return reportWindowPeriodManager;
	}

	public void setReportWindowPeriodManager(
			ReportWindowPeriodManager reportWindowPeriodManager) {
		this.reportWindowPeriodManager = reportWindowPeriodManager;
	}

	public CatalogManager getCatalogManager() {
		return catalogManager;
	}

	public void setCatalogManager(CatalogManager catalogManager) {
		this.catalogManager = catalogManager;
	}

	public DynaBeanManager getDynaBeanManager() {
		return dynaBeanManager;
	}

	public void setDynaBeanManager(DynaBeanManager dynaBeanManager) {
		this.dynaBeanManager = dynaBeanManager;
	}

	public ReportInstanceManager getReportInstanceManager() {
		return reportInstanceManager;
	}

	public void setReportInstanceManager(ReportInstanceManager reportInstanceManager) {
		this.reportInstanceManager = reportInstanceManager;
	}

	public ReportInstance getReportInstance() {
		return reportInstance;
	}

	public void setReportInstance(ReportInstance reportInstance) {
		this.reportInstance = reportInstance;
	}

	public ReportWindowPeriod getReportWindowPeriod() {
		return reportWindowPeriod;
	}

	public void setReportWindowPeriod(ReportWindowPeriod reportWindowPeriod) {
		this.reportWindowPeriod = reportWindowPeriod;
	}

	public String getCatalogGuid() {
		return catalogGuid;
	}

	public void setCatalogGuid(String catalogGuid) {
		this.catalogGuid = catalogGuid;
	}

	public String getObjectGuid() {
		return objectGuid;
	}

	public void setObjectGuid(String objectGuid) {
		this.objectGuid = objectGuid;
	}

	public String getJsonObjects() {
		return jsonObjects;
	}

	public void setJsonObjects(String jsonObjects) {
		this.jsonObjects = jsonObjects;
	}

	public static long getSerialVersionUID() {
		return serialVersionUID;
	}

	public static Logger getLogger() {
		return logger;
	}

	public SoTypeManager getSoTypeManager() {
		return soTypeManager;
	}

	public void setSoTypeManager(SoTypeManager soTypeManager) {
		this.soTypeManager = soTypeManager;
	}

	public DbMetaDataManager getDbMetaDataManager() {
		return dbMetaDataManager;
	}

	public void setDbMetaDataManager(DbMetaDataManager dbMetaDataManager) {
		this.dbMetaDataManager = dbMetaDataManager;
	}

	public String getFilter() {
		return filter;
	}

	public void setFilter(String filter) {
		this.filter = filter;
	}

}
